package com.dataseek.iot.start.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dataseek.iot.core.enums.AlarmType;
import com.dataseek.iot.mysql.entity.Device;
import com.dataseek.iot.mysql.entity.DeviceLog;
import com.dataseek.iot.mysql.entity.LoginUser;
import com.dataseek.iot.mysql.service.impl.AlarmLogServiceImpl;
import com.dataseek.iot.mysql.service.impl.DeviceServiceImpl;
import com.dataseek.iot.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.dataseek.iot.core.constant.DataConst.*;

/**
 * @author cc
 * @Title: 基础定时任务
 * @Description: 基础定时任务
 * @date 2021/10/105:18 下午
 * @since 1.0
 */
@Component
@Slf4j
public class BaseSchedule {

    @Autowired
    RedisUtil redisClient;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    DeviceServiceImpl deviceService;

    @Autowired
    AlarmLogServiceImpl alarmLogService;

    @Value("${mqtt.username}")
    private String username;

    @Value("${mqtt.password}")
    private String password;

    @Value("${mqtt.url}")
    private String url;


    ResponseEntity<JSONObject> restInit(String uri, HttpMethod method){
        HttpHeaders header = new HttpHeaders();
        String auth = username + ":" + password;
        byte[] authentication = auth.getBytes(StandardCharsets.UTF_8);
        byte[] base64Authentication = Base64Utils.encode(authentication);
        String baseCredential = new String(base64Authentication);
        header.add(HttpHeaders.AUTHORIZATION,  "Basic " + baseCredential);
        header.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<JSONObject> request = new HttpEntity<JSONObject>(header);
        return restTemplate.exchange(uri, method, request, JSONObject.class);
    }

//    @Scheduled(fixedRate = 5000)
    public void monitorMQTTClient(){
        StringBuffer uri = new StringBuffer("http://")
                .append(url)
                .append(":")
                .append("8081")
                .append("/api/v4/clients")
                .append("?")
                .append("_page=1&_limit=10");
        ResponseEntity<JSONObject> result = restInit(uri.toString(), HttpMethod.GET);
        JSONArray array = result.getBody().getJSONArray("data");
        List<String> ids = new ArrayList<>();
        if(array.size()>0){
            for(Object o : array){
                Map client = (Map)o;
                //获取 clientId
                String clientId = (String) client.get("clientId");

                //存储or更新客户端信息
                redisClient.set(clientId, o);
                ids.add(clientId);
            }
            //设备总数要根据用户信息查询
            List<Device> list;
            Object o = redisClient.get("user");
            //总在线设备数量
            Integer totalOnlineNum = 0;
            List<String> onlineClients;
            if(Objects.nonNull(o)){
                LoginUser loginUser = (LoginUser)o;
                String[] lineCodes = (loginUser.getLineCode()).split(",");
                QueryWrapper<Device> wrapper = new QueryWrapper<>();
                wrapper.in("line_code", lineCodes);
                list = deviceService.list(wrapper);
                onlineClients = ids.stream().filter(item -> list.contains(item)).collect(Collectors.toList());
                //设备总数
                redisClient.set(DEVICE_TOTAL_NUM, list.size());
                //在线数量
                redisClient.set(ONLINE_NUM,onlineClients.size());
                //离线数量
                redisClient.set(OFFLINE_NUM, list.size()-onlineClients.size());
                //设备报警总数
                List<String> codes = new ArrayList<>();
                for(Device device : list){
                    String code = device.getDeviceCode();
                    codes.add(code);
                }
                wrapper = new QueryWrapper<>();
                wrapper.in("device_code", codes);
                wrapper.eq("alarm_type", AlarmType.HighAlarm.getName())
                        .or().eq("alarm_type", AlarmType.LowAlarm.getName())
                        .or().eq("alarm_type", AlarmType.PosAlarm.getName());
                List<Device> devices = deviceService.list(wrapper);
                //设备报警总数存储
                redisClient.set(CURRENT_ALARM_NUM, devices.size());
            }else{
                list = deviceService.list();
                //设备总数
                log.info("设备总数:{}",list.size());
                redisClient.set(DEVICE_TOTAL_NUM, list.size());
                //在线数量
                Integer onlineNum = list.size()>array.size()? array.size() : list.size();
                log.info("在线设备数量:{}", onlineNum);
                redisClient.set(ONLINE_NUM,onlineNum);
                Integer offlineNum = list.size()>array.size()? list.size()-array.size() : 0;
                log.info("离线设备数量", offlineNum);
                redisClient.set(OFFLINE_NUM, offlineNum);
                //设备报警总数
                Integer alarmDeviceNum = 0;

                for(String deviceCode : ids){
                   QueryWrapper<DeviceLog> wrapper = new QueryWrapper();
                   wrapper.eq("device_code", deviceCode);
                   wrapper.orderByDesc("create_time");
                   DeviceLog log = alarmLogService.getOne(wrapper);

                }
                //设备报警总数
//                log.info("设备报警总数:{}", devices.size());
//                redisClient.set(CURRENT_ALARM_NUM, devices.size());
            }

        }
    }
}
